#include "MyQueue.h"


MyQueue::MyQueue(void)
{
	finished = false;
}


MyQueue::~MyQueue(void)
{
}

int MyQueue::queueManager()
{
	cout<<"WE ARE IN QMANAGER\n";
	unique_lock<mutex> lock(mutQM);
	int num_bl = 0;
	int num_fr = 0;
	
	MyQueue Qp;
	thread Qp_thread(&MyQueue::queueProcessor, &Qp);
	cout<<"QM JUST BEFORE THE LOOP\n";
	while (finished == false)
	{
		cout<<"INSIDE QM LOOP\n";
		condQMadded.wait(lock);

		while (!this->empty())
		{
			num_bl = this->front()->getDirection().num_blocked;
			num_fr = this->front()->getDirection().num_free;
			if ( \
				( \
				 ( \
				  (num_bl == UP \
				  || num_bl == DOWN \
				  || num_bl == LEFT \
				  || num_bl == RIGHT) \
				  || \
				  (num_fr == UP \
				  || num_fr == DOWN \
				  || num_fr == LEFT \
				  || num_fr == RIGHT)\
				 ) \
				  && (this->front()->getCondition() == NOT) \
				) \
				 || \
				( \
				 (
				  (num_bl != UP \
				  || num_bl != DOWN \
				  || num_bl != LEFT \
				  || num_bl != RIGHT \
				  || num_bl != 0) \
				  || \
				  (num_fr != UP \
				  || num_fr != DOWN \
				  || num_fr != LEFT \
				  || num_fr != RIGHT \
				  || num_bl != 0) \
				 ) \
				 && (this->front()->getCondition() != READY) \
				) \
			   )
			{
				lock_guard<mutex> lockg(mutQP);
				Qp.push(this->front());
				cout<<"Qp PUSHED\n";
			}
			condQPadded.notify_one();
			cout<<"Qp ADDED NOTIFIED\n";
			//HERE WE SHOULD NOTIFY QUEUE PROCESSOR
		}
	}
	Qp_thread.join();
	cout<<"WE ARE LEAVING QMANAGER\n";
	return 0;
}

int MyQueue::queueProcessor()
{
	cout<<"WE ARE IN QPROCESSOR\n";
	queue QpGrey, QpWhite, QpBlack;
	const int N = 3;
	queue qp_array[N] = {QpGrey, QpWhite, QpBlack};
	//qp_array[this->front()->getColor()].push(this->front()); causes BOOM!!!!
	
	unique_lock<mutex> lock(mutQP);
	cout<<"QP JUST BEFORE THE LOOP\n";
	while (finished == false)
	{
		cout<<"INSIDE LOOP QPROCESSOR\n";
		condQPadded.wait(lock);
		condBlFinished.wait(lock);
		condWhFinished.wait(lock);
		condGrFinished.wait(lock);
	}
	cout<<"WE ARE LEAVING QPROCESSOR\n";
	return 0;
}

int MyQueue::blackProcessor( Cell *, multimap<int*, Cell*> )
{
	cout<<"BLACKPROCESSOR STARTED\n";
	return 0;
}

int MyQueue::whiteProcessor( Cell *, multimap<int*, Cell*> )
{
	cout<<"WHITEPROCESSOR STARTED\n";
	return 0;
}

int MyQueue::otherProcessor( Cell *, multimap<int*, Cell*> )
{
	cout<<"OTHERPROCESSOR STARTED\n";
	return 0;
}
